/*
 * WLanService.h
 *
 *  Created on: 2023年4月11日
 *      Author: 15271
 */

#ifndef TRUNK_SRC_WLANSERVICE_H_
#define TRUNK_SRC_WLANSERVICE_H_
#include <string>
#include <mutex>
#include "json.h"
#include "Thread/Thread.h"
#include "RouteUtil.h"
#include <map>
#include "Net.h"
#include "LedCnt.h"
#include <thread>


namespace Media{
    #define MAX_PATH 32
    typedef struct IP_Struct{
    	//ip地址划分后各个域的值
    	struct IpAdress_Struct
    	{
    		int first;  
    		int second;  
    		int third;  
    		int forth;
    	}IpAdress,*pIPAdress;
    	//ip地址
    	char szIPAdress[MAX_PATH];
    	//子网掩码
    	char szIPMask[MAX_PATH];
    	IP_Struct()
    	{
    		strcpy(szIPAdress,"");
    		strcpy(szIPMask,"");
    	}
    	IP_Struct(char szIPAdress[],char szIPMask[])
    	{
    		strcpy(this->szIPAdress,szIPAdress);
    		strcpy(this->szIPMask,szIPMask);
    	}
    }IP,*pIP;

    
	using namespace std;
	class WlanService{
	private:	    
    	const string ConfigPath = "/mnt/mtd/Config/Config11";
    	const string wifiPath = "Wifi";
        enum useApChannel
		{
			apChannel_5180HZ = 36,
			apChannel_5200HZ = 40,
			apChannel_5220HZ = 44,
			apChannel_5240HZ = 48,
			// apChannel_52 = 52,
			// apChannel_56 = 56,
			// apChannel_60 = 60,
			// apChannel_64 = 64,
			apChannel_5745HZ = 149,
			apChannel_5765HZ = 153,
			apChannel_5785HZ = 157,
			apChannel_5805HZ = 161,
			apChannel_165 = 165,
		};
    	const unsigned int defaultApChannel = 44;

    	#define INI_NETWORK_PATH "/mnt/mtd/Config/netWork.ini"
        #define LAN_ETH0   "eth0"
        #define LAN_WLAN0  "wlan0"
        #define LAN_WLAN1  "wlan1"

        const std::string apWlanAddr[3] = {"172.16.10.0", "192.168.10.0", "172.16.115.0", };


        #define PING_CMD	    "/bin/ping -I eth0 -c 1 -W 3 %s > %s"
        #define TMP_PING_PATH	"/var/pingInternet"
        #define RECV1ICMPPKT	"1 packets received"
        #define PING_URL	    "8.8.8.8"
        	
	public:
		//单例
		static WlanService *instance();

		//连接wifi
		bool connectWifi(string ssid, string key, string bssid = "", int time_sec = 10);
		
		bool openApService(string Password, string FreqBand, int Retransmit, string ssid);
		
		bool scanAP(Json::Value &apList);

		bool setWiredNetwork(string IP, string Mask, string GateWay, bool Dhcp);
		
		bool getWiredNetwork(Json::Value &table);	

		bool startDynamicRouteService();
		
		bool getWirelessStatus(string &bssid, string &ssid, unsigned int &channel);

		bool getWirelessStatus();

		bool wlanTranspond();

		bool GetInterfaceWishaddr(char *pInterfaceName, int param, string &addr);

		bool isSameSubnet(void);

		bool checkInternetPing(string ip);

		bool dhcpcThreadFuc(const string NetCard);

		int getWifiApSignalDb(string ssid);

		string getWlanGateway();

		bool getApChannel(string filename, int &channel);
		
		bool setWlanStaChannel(int channel);

		bool setTailMatch(bool value);

		bool getApInfo(string& apInfo);
		bool getApInfo(string& apName, string& apPassword);

		bool getStaInfo(std::string &ssid);

		bool pingUtil(std::string netCard, std::string ip);

		bool startMirrorWeaknetDetect(std::string netCard, std::string clientAddr, int maxTimeout, int avgPacketnum, int avgMaxTimeout);
		bool stopMirrorWeaknetDetect();
		bool MirrorWeaknetDetectThread(std::string netCard, std::string clientAddr, int maxTimeout, int avgPacketnum, int avgMaxTimeout);
		std::string  MirrorNetcard();
		std::string  getMirrorIp();
		bool  setMirrorIp(std::string ip);
	private:
		//构造析构
		WlanService();
		bool initWlan();
		bool readConfig(Json::Value &wifiTable);
		unsigned int  getApChannels(void);
		~WlanService();

		bool disConnWifi();

		void wifiConnectCheck();

		bool JudgeIp(char *szIP,IP_Struct::IpAdress_Struct *ipAdress);

		bool IsSameNetworkSegment(char *szIPAdress,char *szMask,char *szIPAdresss1, char *szMask1);

		void NetThreadProc(Fdt::Thread *thread);

		bool setDefaultRoute(string netCard);

		bool setOrdinaryRoute(int ethConnStat, int wlanConnStat);

		bool dynamicWiredNetwork();
		
		bool staticWiredNetwork(string IP, string Mask, string GateWay);

		bool apFilter(WLAN_DEVICE_EXT *pApList, unsigned int apnum);

		bool chooseAp(WLAN_DEVICE_EXT *opt1, WLAN_DEVICE_EXT *opt2, WLAN_DEVICE_EXT *obj);

		//dhcp失败之后开启LLA
		bool APIPA(char *IPADDR);

		bool  getIpAddress(vector<string> &ips);

		std::vector<std::string> stringSplit(const std::string& str, char delim); 

		int ipNetmaskToNsid(const char* ip, const char* netmask, char* NSID);	

		std::string trimString(const std::string& input);

		void CheckNetworkThread();

		bool CheckNetwork(const std::vector<std::string>& httpDst);

	private:
		static WlanService *sm_WlanService;
		static mutex sm_WlanMutex;
		bool m_initFlag;
		int  m_ap_channel;
		int  m_wifi_channel;
		bool m_sta_mutex_mark;
		bool m_ap_mutex_mark;
		std::string 						m_curSsid = "";
		std::string 						m_curKeys = "";
		std::string							m_curBssid = "";
		mutex m_openApLock;
		mutex m_scanApLock;
		mutex m_readwriteLock;
		std::recursive_mutex m_connMutex;
		mutex m_channelLock;

        RouteUtil                           m_routeManager;
		std::string                         m_wlanGateway;
		std::string                         m_wlanNetmask;
		std::string                         m_wlanDest;
		std::string                         m_wiredGateway;
		std::string                         m_wiredNetmask;
		std::string                         m_wiredDest;
		
		bool                                m_connWifiFlg = false;
		bool                                m_connWiredFlg = false;
		bool                                m_dhcpFlg = false;

		std::string                         m_wlanTransCard;
		
		map<string, WLAN_DEVICE_EXT> 		m_bssidInfo;

		mutex                               m_transSetMutex;

		bool                                m_wifiConStatus = false;

 		bool								m_udhcpcEvent = false;

		thread 								m_EthThread;

		bool								m_EthThreadMark = false;

		bool								m_EthThreadExit = true;

		thread 								m_WlanThread;

		bool								m_WlanThreadMark = false;

		bool								m_WlanThreadExit = true;

		int									m_WlanStaChannel = 0;

		bool 								m_tailMatch = false;

		std::atomic<bool> 					m_weakNetThread{false};
		std::atomic<bool> 					m_weakNetRunning{false};
		std::mutex							m_weakDetechLock;

		std::atomic<bool> 					m_ExtranetThreadExit{true};
		std::atomic<bool> 					m_ExtranetThreadRuning{false};
		std::atomic<bool> 					m_ExtranetState{false};

		std::string							m_mirrorIp = "";
		std::mutex							m_mirrorIpLock;

		std::string                         m_apInfo;

		std::string 						m_apName;
		std::string							m_apPassword;
		Fdt::Thread 						m_netStateThread{ "NetStateStream" };//thread放在最后,保证thread最后构造,最先析构		
	};
}
#endif /* TRUNK_SRC_WLANSERVICE_H_ */
